#!/usr/bin/env python3
#-*- coding:utf-8 -*-

import codecs
import os
import sys
import logging
import getopt

from ExtraerVerbosYSustantivos import *
from Limpieza import *
from ContarPalabras import *

def armarTareas():
	return ('limpieza','extraer','contar')

def usage():
	print ' Prototipo de control de tareas: Escenario crawler de archivos de texto en español.'
	print '  Forma de uso: python prototipo.py --file="nombre de archivo"'
	print '   --file, -f: Nombre del archivo a procesar en el pipe.'
	print '   --help, -h: Mostrar este mensaje de ayuda.'
	print '\n'
	print '  El pipe esta compuesto por las tareas: '+', '.join(armarTareas())+'.\n'
	print '   - limpieza: Crea una instancia de "Limpieza.py"; el resultado de esta tarea son lineas con palabras separadas por espacios y todas minusculas y tambien elimina un conjunto de palabras de una lista negra.'
	print '   - extraer: Crea una instancia de "ExtraerVerbosYSustantivos.py"; el resultado de esta tarea son lineas con palabras que son verbos o son sustantivos.'
	print '   - contar: Crea una instancia de "ContarPalabras.py"; el resultado es un listado de pares (palabra,cardinalidad) separados por un espacio, ademas informa las de mayor ocurrencia en el registro.'

def armarNoLeer(archivo):
	# Si existen errores previos. Armo una lista con el numero de linea a obviar.
	lineasConErrores = list()
	errores = None
	if os.path.isfile(archivo+'.err'):
		errores = open(archivo+'.err','r')
	if (errores != None):
		for e in errores:
			try:
				aux1 = e.index("[")
				aux2 = e.index("]: ")

				aux = e.substr(aux1,aux2-aux1)
				lineasConErrores.append(int(aux))
			except:
				pass

		errores.close()
	errores = None
	return lineasConErrores

def armarLogger(archivo):
	formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
	logger = logging.getLogger(archivo+'.log')
	hl = logging.FileHandler(archivo+'.log')
	hl.setFormatter(formatter)
	logger.addHandler(hl)
	logger.setLevel(logging.INFO)

	return logger

def armarErrores(archivo):
	formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
	errores = logging.getLogger(archivo+'.err')
	he = logging.FileHandler(archivo+'.err')
	he.setFormatter(formatter)
	errores.addHandler(he)
	errores.setLevel(logging.ERROR)
	
	return errores

def armarEntrada(archivo):
	return open(archivo,'r')
#	entrada = codecs.open(archivo,'r','utf-8')

def armarSalida(archivo):
	return open(archivo,'w')
#	salida = codecs.open(archivo+'.'+tarea,'w','utf-8')

# A partir de un nombre de archivo de entrada procesa el archivo y obtiene los resultados necesarios en todas las etapas.
# TODO MAIN CON ARGUEMENTOS.
def main():
	try:
		opts, args = getopt.getopt(sys.argv[1:], "hft:", ["help", "file="])
	except getopt.GetoptError:
		# presentar información de ayuda y salir:
		usage()
		sys.exit(2)

	archivo = None
	tarea = None
	for o,a in opts:
		if o in ('-h', '--help'):
			usage()
			sys.exit(0)
		if o in ('-f', '--file'):
			archivo = a
	if (archivo is None):
		usage()
		sys.exit(2)

	# Permite generar el pipeline con las tareas una sola vez, y luego asociar cada tarea a los archivos correspondientes.
	pipeline = list()
	for t in armarTareas():
		if t == 'limpieza':
			pipeline.append( Limpieza(t) )
		if t == 'extraer':
			pipeline.append( ExtraerVerbosYSustantivos(t) )
		if t == 'contar':
			pipeline.append( ContarPalabras(t) )

	for tarea in pipeline:
		reintentos = 1
		tareaError = Tarea.NOERROR
		# mientras no logre terminar de procesar el archivo en la tarea indicada.
		while ( (tareaError != Tarea.ERROR) and (reintentos > 0) ):
			reintentos -= 1

			try:
				# Armo los archivo de entrada.
				entrada = armarEntrada(archivo)
				noLeer = armarNoLeer(archivo+'.'+tarea.nombre)
				salida = armarSalida(archivo+'.'+tarea.nombre)
				logger = armarLogger(archivo+'.'+tarea.nombre)
				errores = armarErrores(archivo+'.'+tarea.nombre)

				tarea.configurar(entrada, noLeer, salida, logger, errores)
				tareaError = tarea.do()

				# Libero los recuros.
				entrada.close()
				salida.close()
				logger = None
				errores = None
				noLeer = None

			except Exception as e:
				sys.stdout.write('E: '+str(e))
				tareaError = Tarea.ERROR
	
			sys.stdout.write('Realizado: '+tarea.nombre+'('+archivo+')\n')
		archivo = archivo + '.' + tarea.nombre

if __name__ == '__main__':
	sys.exit(main())

